package com.zhang.IO.NIO;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

public class NioClientHandler implements Runnable {
 private Selector selector;

 NioClientHandler(Selector selector)
 {
     this.selector=selector;
 }
    @Override
    public void run() {
        try {
            for (;;)  //和while(true)一样
        {
            /**
             * 获取可以的Channel数量
             */
            int readyChannels= 0;//是一个阻塞方法，只有上面监听的就绪了才会返回

                readyChannels = selector.select();

            if ( readyChannels==0) continue;
            /**
             * 获取可用的Channel集合，每次获取到都会放入到SelectedKeys中，
             * 所以下面需要删除掉已处理的
             */
            Set<SelectionKey> selectionKeys= selector.selectedKeys();
            Iterator iterator=selectionKeys.iterator();
            while (iterator.hasNext())
            {
                /**
                 * 处理Channel内容
                 */
                SelectionKey selectionKey= (SelectionKey) iterator.next();

                /**
                 * 移除Set中当前的SelectionKey
                 */
                iterator.remove();

                //7.根据状态调用业务方法
                /**
                 * 如果是可读事件
                 */
                if (selectionKey.isReadable())
                {
                    readHandler(selectionKey,selector);
                }

            }
        }
        } catch (IOException e) {
        e.printStackTrace();
    }
    }
    /**
     * 处理可读事件处理器
     */
    private void readHandler(SelectionKey selectionKey,Selector selector) throws IOException {
        //从SelectionKey中获取已就绪的Channel
        SocketChannel socketChannel= (SocketChannel) selectionKey.channel();
        //创建buffer
        ByteBuffer byteBuffer=ByteBuffer.allocate(1024);

        String request="";
        //循环读取服务端响应信息
        while(socketChannel.read(byteBuffer)>0)
        {
            //切换为buffer为读模式
            byteBuffer.flip();
            /**
             * 读取buffer中的内容
             */
            request+=Charset.forName("UTF-8").decode(byteBuffer);
        }
        //将channel再次注册到selector上，监听他的可读事件
        socketChannel.register(selector,SelectionKey.OP_READ);
        //将服务器的消息打印到本地
        if (request.length()>0)
        {
            System.out.println("服务器：  "+request);
        }
    }

}
